package ren.kane.phoenix.quartz;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

/**
 * @author renrk(1275) on 2018-10-23 8:52 PM
 **/
@CrossOrigin
@RestController
@RequestMapping("/phoenix/quartz")
@Api(value = "Quartz控制类", description = "Quartz的相关接口API")
public class QuartzController {

    private static final String JOB_DEFAULT_CLASS = "ren.kane.phoenix.quartz.TestJob";
    private static final String JOB_DEFAULT_GROUP = "phoenix_group";

    @Autowired
    private Scheduler scheduler;

    @PostMapping("/add")
    @ApiOperation(value = "添加定时任务", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test"),
        @ApiImplicitParam(paramType = "query", dataType = "string", name = "cronExpression", value = "cron表达式", required = true, defaultValue = "0/10 * * * * ? *")
    })
    public void addJob(@RequestParam("jobName") String jobName, @RequestParam("cronExpression") String cronExpression) {
        try {
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(JOB_DEFAULT_CLASS);
            // 任务
            JobDetail jobDetail = newJob(jobClass).withIdentity(jobName, JOB_DEFAULT_GROUP).build();
            // 触发器
            Trigger trigger = newTrigger().withIdentity(jobName, JOB_DEFAULT_GROUP)
                .withSchedule(cronSchedule(cronExpression)).build();
            // 调度器
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/modify")
    @ApiOperation(value = "修改定时任务触发时间", httpMethod = "POST")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test"),
        @ApiImplicitParam(paramType = "query", dataType = "string", name = "newCron", value = "cron表达式", required = true, defaultValue = "0/5 * * * * ? *")
    })
    public void modifyJobTime(@RequestParam("jobName") String jobName, @RequestParam("newCron") String newCron) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, JOB_DEFAULT_GROUP);
            CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (!newCron.equalsIgnoreCase(cronTrigger.getCronExpression())) {
                cronTrigger = newTrigger().withIdentity(triggerKey).withSchedule(cronSchedule(newCron)).build();
                scheduler.rescheduleJob(triggerKey, cronTrigger);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/pause")
    @ApiOperation(value = "暂停定时任务", httpMethod = "POST")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test")
    public void pauseJob(@RequestParam("jobName") String jobName) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName, JOB_DEFAULT_GROUP));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/trigger")
    @ApiOperation(value = "立即执行定时任务", httpMethod = "POST")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test")
    public void triggerJob(@RequestParam("jobName") String jobName) {
        try {
            scheduler.triggerJob(JobKey.jobKey(jobName, JOB_DEFAULT_GROUP));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/resume")
    @ApiOperation(value = "恢复定时任务", httpMethod = "POST")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test")
    public void resumeJob(@RequestParam("jobName") String jobName) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName, JOB_DEFAULT_GROUP));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/remove")
    @ApiOperation(value = "删除定时任务", httpMethod = "POST")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test")
    public void removeJob(@RequestParam("jobName") String jobName) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName, JOB_DEFAULT_GROUP));
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    @PostMapping("/status")
    @ApiOperation(value = "查看定时任务状态", httpMethod = "POST")
    @ApiImplicitParam(paramType = "query", dataType = "string", name = "jobName", value = "任务名称", required = true, defaultValue = "test")
    public String getJobStatus(@RequestParam("jobName") String jobName) {
        try {
            return Trigger.TriggerState.NORMAL
                .equals(scheduler.getTriggerState(TriggerKey.triggerKey(jobName, JOB_DEFAULT_GROUP))) ? "on" : "off";
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return "off";
    }
}
